#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


struct Node{
    void* next;
    int data;
};

typedef void (*PFN_VISIT)(struct Node* item);


struct Node* create_node(int val) {
    struct Node* item = (struct Node*)malloc(sizeof(struct Node));
    assert(item);
    item->next = NULL;
    item->data = val;
    return item;
}

struct Node* link_add(struct Node* head, struct Node* item) {
    assert(head);
    assert(item);
    struct Node* p = head;
    while (p->next != NULL) {
        p = p->next;
    }
    p->next = item;
    return head;
}


void print_node(struct Node* item) {
    assert(item);
    printf("address:[%p], value:[%d]\n", item, item->data);
}

void free_node(struct Node* item) {
    assert(item);
    free(item);
}


void travel_link(struct Node* head, PFN_VISIT pfn_visit) {
    struct Node* p = head;
    while (p->next != NULL) {
        p = p->next;
        pfn_visit(p);
    }
}


void test_link() {
    struct Node* head = (struct Node*)malloc(sizeof(struct Node));
    head->next = NULL;
    head->data = -1;

    struct Node* item = NULL;
    item = create_node(1);
    head = link_add(head, item);

    item = create_node(2);
    head = link_add(head, item);

    item = create_node(3);
    head = link_add(head, item);

    PFN_VISIT pfn_visit = print_node;
    travel_link(head, pfn_visit);

    pfn_visit = free_node;
    travel_link(head, pfn_visit);

}


int main(int argc, char** argv) {
    test_link();
}
